package com.blog.cmrpersonalblog.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.cmrpersonalblog.dto.category.request.CategoryBatchOperationRequest;
import com.blog.cmrpersonalblog.dto.category.request.CategoryCreateRequest;
import com.blog.cmrpersonalblog.dto.category.request.CategoryQueryRequest;
import com.blog.cmrpersonalblog.dto.category.request.CategoryUpdateRequest;
import com.blog.cmrpersonalblog.dto.category.response.CategoryManagementResponse;
import com.blog.cmrpersonalblog.entity.ArticleCategory;
import com.blog.cmrpersonalblog.mapper.CategoryMapper;
import com.blog.cmrpersonalblog.service.CategoryManagementService;
import com.blog.cmrpersonalblog.service.UserActivityService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 分类管理服务实现类
 */
@Slf4j
@Service
public class CategoryManagementServiceImpl implements CategoryManagementService {

   @Resource
    private CategoryMapper categoryMapper;

   @Resource
    private UserActivityService userActivityService;

    @Override
    public IPage<CategoryManagementResponse> getCategoryList(CategoryQueryRequest queryRequest) {
        Page<CategoryManagementResponse> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());
        return categoryMapper.selectCategoryManagementPage(page, queryRequest);
    }

    @Override
    public CategoryManagementResponse getCategoryDetail(Long categoryId) {
        if (categoryId == null) {
            return null;
        }
        return categoryMapper.selectCategoryDetailById(categoryId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createCategory(CategoryCreateRequest createRequest, Long operatorId) {
        try {
            if (!createRequest.isValid()) {
                throw new RuntimeException("请求参数无效");
            }

            // 检查分类名称是否已存在
            if (existsCategoryName(createRequest.getName(), null)) {
                throw new RuntimeException("分类名称已存在");
            }

            // 创建分类
            ArticleCategory category = new ArticleCategory();
            BeanUtils.copyProperties(createRequest, category);
            category.setCreateTime(LocalDateTime.now());
            category.setUpdateTime(LocalDateTime.now());

            int result = categoryMapper.insert(category);
            if (result > 0) {
                // 记录创建活动
                userActivityService.recordActivity(operatorId, "CATEGORY_CREATED", "创建分类",
                    category.getId(), "category", "SUCCESS", 
                    Map.of("categoryName", createRequest.getName()));

                log.info("分类创建成功: categoryId={}, name={}, operatorId={}", 
                    category.getId(), createRequest.getName(), operatorId);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("分类创建失败", e);
            throw new RuntimeException("分类创建失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCategory(CategoryUpdateRequest updateRequest, Long operatorId) {
        try {
            if (!updateRequest.isValid()) {
                throw new RuntimeException("请求参数无效");
            }

            // 检查分类是否存在
            ArticleCategory existingCategory = categoryMapper.selectById(updateRequest.getId());
            if (existingCategory == null) {
                throw new RuntimeException("分类不存在");
            }

            // 检查分类名称是否已存在（排除当前分类）
            if (existsCategoryName(updateRequest.getName(), updateRequest.getId())) {
                throw new RuntimeException("分类名称已存在");
            }

            // 更新分类
            ArticleCategory category = new ArticleCategory();
            BeanUtils.copyProperties(updateRequest, category);
            category.setUpdateTime(LocalDateTime.now());

            int result = categoryMapper.updateById(category);
            if (result > 0) {
                // 记录更新活动
                userActivityService.recordActivity(operatorId, "CATEGORY_UPDATED", "更新分类",
                    category.getId(), "category", "SUCCESS", 
                    Map.of("categoryName", updateRequest.getName(), 
                           "oldName", existingCategory.getName()));

                log.info("分类更新成功: categoryId={}, name={}, operatorId={}", 
                    category.getId(), updateRequest.getName(), operatorId);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("分类更新失败", e);
            throw new RuntimeException("分类更新失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCategory(Long categoryId, Long operatorId) {
        try {
            // 检查分类是否存在
            ArticleCategory category = categoryMapper.selectById(categoryId);
            if (category == null) {
                throw new RuntimeException("分类不存在");
            }

            // 检查分类是否被文章使用
            if (isCategoryUsedByArticles(categoryId)) {
                throw new RuntimeException("分类正在被文章使用，无法删除");
            }

            // 删除分类
            int result = categoryMapper.deleteById(categoryId);
            if (result > 0) {
                // 记录删除活动
                userActivityService.recordActivity(operatorId, "CATEGORY_DELETED", "删除分类",
                    categoryId, "category", "SUCCESS", 
                    Map.of("categoryName", category.getName()));

                log.info("分类删除成功: categoryId={}, name={}, operatorId={}", 
                    categoryId, category.getName(), operatorId);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("分类删除失败", e);
            throw new RuntimeException("分类删除失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> batchOperateCategories(CategoryBatchOperationRequest batchRequest, Long operatorId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (!batchRequest.isValid()) {
                throw new RuntimeException("请求参数无效");
            }

            CategoryBatchOperationRequest.OperationType operationType = batchRequest.getOperationTypeEnum();
            int affectedRows = 0;

            switch (operationType) {
                case ENABLE:
                    affectedRows = categoryMapper.batchUpdateCategoryStatus(batchRequest.getCategoryIds(), 1);
                    break;
                case DISABLE:
                    affectedRows = categoryMapper.batchUpdateCategoryStatus(batchRequest.getCategoryIds(), 0);
                    break;
                case DELETE:
                    // 检查是否有分类被文章使用
                    for (Long categoryId : batchRequest.getCategoryIds()) {
                        if (isCategoryUsedByArticles(categoryId)) {
                            throw new RuntimeException("部分分类正在被文章使用，无法删除");
                        }
                    }
                    affectedRows = categoryMapper.batchDeleteCategories(batchRequest.getCategoryIds());
                    break;
                default:
                    throw new RuntimeException("不支持的操作类型: " + operationType.getDescription());
            }

            result.put("success", affectedRows > 0);
            result.put("affectedRows", affectedRows);
            result.put("operation", operationType.getDescription());

            if (affectedRows > 0) {
                // 记录批量操作活动
                userActivityService.recordActivity(operatorId, "CATEGORY_BATCH_OPERATION", 
                    "批量操作分类: " + operationType.getDescription(),
                    null, "category", "SUCCESS", 
                    Map.of("operation", operationType.getDescription(), 
                           "categoryIds", batchRequest.getCategoryIds(),
                           "affectedRows", affectedRows));

                log.info("分类批量操作成功: operation={}, affectedRows={}, operatorId={}", 
                    operationType.getDescription(), affectedRows, operatorId);
            }

            return result;
        } catch (Exception e) {
            log.error("分类批量操作失败", e);
            result.put("success", false);
            result.put("error", e.getMessage());
            return result;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean enableCategory(Long categoryId, Long operatorId) {
        try {
            ArticleCategory category = categoryMapper.selectById(categoryId);
            if (category == null) {
                throw new RuntimeException("分类不存在");
            }

            category.setStatus(1);
            category.setUpdateTime(LocalDateTime.now());
            
            int result = categoryMapper.updateById(category);
            if (result > 0) {
                userActivityService.recordActivity(operatorId, "CATEGORY_ENABLED", "启用分类",
                    categoryId, "category", "SUCCESS", 
                    Map.of("categoryName", category.getName()));
                
                log.info("分类启用成功: categoryId={}, operatorId={}", categoryId, operatorId);
                return true;
            }
            
            return false;
        } catch (Exception e) {
            log.error("分类启用失败", e);
            throw new RuntimeException("分类启用失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean disableCategory(Long categoryId, Long operatorId) {
        try {
            ArticleCategory category = categoryMapper.selectById(categoryId);
            if (category == null) {
                throw new RuntimeException("分类不存在");
            }

            category.setStatus(0);
            category.setUpdateTime(LocalDateTime.now());
            
            int result = categoryMapper.updateById(category);
            if (result > 0) {
                userActivityService.recordActivity(operatorId, "CATEGORY_DISABLED", "禁用分类",
                    categoryId, "category", "SUCCESS", 
                    Map.of("categoryName", category.getName()));
                
                log.info("分类禁用成功: categoryId={}, operatorId={}", categoryId, operatorId);
                return true;
            }
            
            return false;
        } catch (Exception e) {
            log.error("分类禁用失败", e);
            throw new RuntimeException("分类禁用失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCategorySortOrder(Long categoryId, Integer sortOrder, Long operatorId) {
        try {
            ArticleCategory category = categoryMapper.selectById(categoryId);
            if (category == null) {
                throw new RuntimeException("分类不存在");
            }

            int result = categoryMapper.updateCategorySortOrder(categoryId, sortOrder);
            if (result > 0) {
                userActivityService.recordActivity(operatorId, "CATEGORY_SORT_UPDATED", "更新分类排序",
                    categoryId, "category", "SUCCESS", 
                    Map.of("categoryName", category.getName(), 
                           "oldSortOrder", category.getSortOrder(),
                           "newSortOrder", sortOrder));
                
                log.info("分类排序更新成功: categoryId={}, sortOrder={}, operatorId={}", 
                    categoryId, sortOrder, operatorId);
                return true;
            }
            
            return false;
        } catch (Exception e) {
            log.error("分类排序更新失败", e);
            throw new RuntimeException("分类排序更新失败: " + e.getMessage());
        }
    }

    @Override
    public List<ArticleCategory> getEnabledCategories() {
        return categoryMapper.selectEnabledCategories();
    }

    @Override
    public boolean existsCategoryName(String name, Long excludeId) {
        ArticleCategory category = categoryMapper.selectCategoryByName(name, excludeId);
        return category != null;
    }

    @Override
    public boolean isCategoryUsedByArticles(Long categoryId) {
        return categoryMapper.isCategoryUsedByArticles(categoryId);
    }

    @Override
    public Map<String, Object> getCategoryStatistics() {
        return categoryMapper.selectCategoryStatistics();
    }

    @Override
    public List<Map<String, Object>> getCategoryStatusDistribution() {
        return categoryMapper.selectCategoryStatusDistribution();
    }

    @Override
    public List<Map<String, Object>> getCategoryUsageStatistics() {
        return categoryMapper.selectCategoryUsageStatistics();
    }

    @Override
    public Integer getNextSortOrder() {
        Integer maxSortOrder = categoryMapper.selectMaxSortOrder();
        return maxSortOrder == null ? 1 : maxSortOrder + 1;
    }

    @Override
    public Long getCategoryArticleCount(Long categoryId) {
        return categoryMapper.selectArticleCountByCategoryId(categoryId);
    }

    @Override
    public Long getCategoryPublishedArticleCount(Long categoryId) {
        return categoryMapper.selectPublishedArticleCountByCategoryId(categoryId);
    }
}
